Suivre ces slides sur Internet…​

http://bit.ly/jmb-cpoa
http://bit.ly/jmb-cpoa
http://iut-blagnac.github.io/cpoa/

Plan

  • Retour TP1

  • Premiers patrons

Retour TP1

Moulinette (Ruby) de note automatique
# -*- coding: utf-8 -*-
# usage: ruby noteModel.rb [directory] [file]

MODEL_NAME = ARGV[1] ? ARGV[1] : "TP1.uml"
NOTES_FILE = "notes.csv"

studentDirectory = ARGV[0] ? ARGV[0] : "."
studentModelFileName = studentDirectory+"/"+MODEL_NAME
puts "Checking " + studentModelFileName

$assertFileContains = [
 /@startuml/m,
 /@enduml/m,
 /abstract Personnage/m,
 /Personnage\s+--> ".*" ComportementArme/m,
 /interface\s+ComportementArme/m,
 /ComportementArme\s+<\|\.\./m,
]


notestr = ""
# test file
notestr += (File.exists?(studentModelFileName)) ? '.' : 'F'

# test file contents
fileContent = File.read(studentModelFileName)

$assertFileContains.each {|re|
 notestr += (fileContent =~ re) ? '.' : 'F'
}

# status
result = notestr.gsub('F','').size.to_s+'/'+notestr.size.to_s+";\n"
bilan = ARGV[0]+';'+notestr+';'+result
print notestr
print result

destfile = File.new(NOTES_FILE,"a")
destfile.write(bilan)
destfile.close()
Moyenne: 11/20 !!

Retour TP1 (suite)

Attendus

70

Rendus

43 (61%) ⇒ 27 0/20

Nom OK

16 (37% des rendus) ⇒ 16 0/20 de plus normalement

Exemple de noms : TP1-Toto-G1A.uml, TP1.zip, tp1.uml, TP1.txt, TP1.png, TD1.uml

20/20

31

17/20

5

14/20

2

11/20

1

09/20

2

03/20

2

Moy.

11/20

Exemples de bons principes

SOLID:

  • Single Responsibility Principle

  • Open-Closed Principle

  • Liskov Substitution Principle

  • Interface Segregation Principle

  • Dependency Inversion Principle

Single Responsibility Principle

solid s
Responsabilité => Sujet à changement

Open-Closed Principle

solid o
Ouvert à l'extension mais fermé à la modification

Open-Closed Principle (suite)

Ainsi, une fois écrite et testée, une classe ne devrait être modifiée que pour être corrigée! Toute modification devrait être possible par extension.

Liskov Substitution Principle

LSP : le principe

solid l
Une classe doit pouvoir être remplacée par une instance d'un de ses
sous-types, sans modifier la cohérence du programme

LSP : un exemple

Un carré est un rectangle a deux côtés égaux.

carre
Question
Peut-on toujours substituer un Carré à la place d’un Rectangle ?

Vraiment?

Réponse (Rectangle.java)
class Rectangle
{
	protected int m_width;
	protected int m_height;

	public void setWidth(int width){
		m_width = width;
	}

	public void setHeight(int height){
		m_height = height;
	}


	public int getWidth(){
		return m_width;
	}

	public int getHeight(){
		return m_height;
	}

	public int getArea(){
		return m_width * m_height;
	}
}

Vraiment?

Réponse (Square.java)
// Violation of Likov's Substitution Principle
class Square extends Rectangle
{
	public void setWidth(int width){
		m_width = width;
		m_height = width;
	}

	public void setHeight(int height){
		m_width = height;
		m_height = height;
	}

}

Vraiment?

Réponse (Square.java - suite)
class LspTest
{
	private static Rectangle getNewRectangle()
	{
		// it can be an object returned by some factory ...
		return new Square();
	}

	public static void main (String args[])
	{
		Rectangle r = LspTest.getNewRectangle();

		r.setWidth(5);
		r.setHeight(10);
		// User knows that r is a rectangle.
		// It assumes that he's able to set the width and height as for the base class

		System.out.println(r.getArea());
		// Now she's surprised to see that the area is 100 instead of 50.
	}
}

Et l’inverse?

rectangle

Même problème

Réponse (Rectangle.java)
class LspTest
{
	private static Square getNewSquare()
	{
		// it can be an object returned by some factory ...
		return new Rectangle();
	}

	public static void main (String args[])
	{
		Square s = LspTest.getNewSquare();

		s.setWidth(5);
		// User knows that r is a rectangle.
		// It assumes that he's able to set the width and height as for the base class

		System.out.println(s.getArea());
		// Now she's surprised to see that the area is 0 instead of 25.
	}
}

Interface Segregation Principle

solid i
Préférer plusieurs interfaces spécifiques pour chaque client plutôt qu'une seule interface générale

Dependency Inversion Principle

solid d
Il faut dépendre des abstractions, pas des implémentations

DIP : explications

Ce principe indique :

  • Les modules de haut niveau (abstraits) ne doivent pas dépendre des modules de bas niveau. Les deux doivent dépendre d’abstractions.

  • Les abstractions ne doivent pas dépendre des détails d’implémentation. C’est l’inverse : les détails doivent dépendre des abstractions.

Ainsi ce principe va à l’encontre de l’intuition classique.

Exemple (bad)

dip bad
Figure 1. Exemple de code violant le principe d’inversion des dépendances

Exemple (good)

dip
Figure 2. Exemple de code ne violant plus le principe d’inversion des dépendances

SOLID et patrons

QUESTION

Lesquels des 5 principes SOLID s’appliquent bien à Strategy ?

solid s

solid o

solid l

solid i

solid d

SOLID et patrons (éléments de réponses)

GRASP

The critical design tool for software development is a mind well educated in design principles. It is not the UML or any other technology.

— Craig Larman
2005

Il s’agit d’un ensemble de patrons, plutôt orientés conception (UML). Nous en aborderons certains au travers des exemples de ce module (cf. [Larman05]).

Les patrons : comment ça marche ?

Intérêt

  • Réponses éprouvées à des problèmes récurrents

  • Vocabulaire commun

T’as qu’à utiliser une factory!

QUESTION

Qui fait la nuit de l’info ?

N2I 2017

Éléments de définition

  • Nom

  • Problème

  • Solution

  • Conséquences

Exemple pour Strategy :

Nom

Strategy

Problème

Situations où il est nécessaire de pouvoir définir dynamiquement les algorithmes utilisés.

Solution

Définir une famille d’algorithmes, encapsuler chacun d’eux en tant qu’objet, et les rendre interchangeables.

Conséquences

Ce patron laisse les algorithmes changer indépendamment des clients qui les emploient.

Singleton

Principes de conception

Pas de nouveau principes de conception particuliers pour le patron [singleton]

Patron Singleton

Note
Design pattern : Singleton

Singleton garantit qu’une classe n’a qu’une seule instance et fournit un point d’accès global à cette instance.

singleton

Patron Singleton

google singleton

Exemples d’utilisation du patron Singleton

Quelques exemple de l’utilisation industrielle de [singleton] :

  • Thread pools (pour contrôler les threads)

  • Connexions SQL

  • Objets de type Registry

  • Objets gérant les préférences utilisateur

  • Caches

  • Les classes Factory

  • …​

Implémentations Java du patron Singleton

Pour résumer les (bonnes) implémentations Java :

  • Initialisation directe de la variable instance.

  • Initialisation dans un bloc static.

  • Utilisation d’un enum à la place d’une classe.

Initialisation directe de la variable instance

    public final class Singleton {
      private final static volatile Singleton instance = new Singleton();
      public final static Singleton getInstance() { return instance; }
      private Singleton() {}
      }
On n’a pas vu cette implémentation en TD!

Initialisation dans un bloc static

public final class Singleton {
        private static volatile Singleton instance = null;
        static {
          instance = new Singleton();
        }
        public final static Singleton getInstance() { return instance; }
        private Singleton() {}
        }

Utilisation d’un enum

        public enum Singleton {
          SINGLETON;
          public static Singleton getInstance() { return SINGLETON; }
        }
  • On n’a pas vu cette implémentation en TD!

  • Les enum, bien connues en C, sont apparues à la version 1.5 de Java!

Exemple d’utilisation d’un enum

Exemple d’utilisation de ce type d’implémentation

public enum MonSingleton {
  INSTANCE;

  private String attribute = "World";

  public String sayHello() {
    return "Hello " + attribute;
  }
}

Et on l’appelle avec :

MonSingleton.INSTANCE.sayHello();

Pourquoi un enum ?

Intérêts/Limites d’utiliser un enum :

  • les enumérations classiques sont thread-safe car elles sont initialisées par le classloader

  • on ne peut pas utiliser l’héritage

Time for a quizz!

QUESTION
  • Connectez-vous sur : http://www.socrative.com/ (student login)

  • Ou téléchargez l’application pour étudiant socrative2

  • Choisissez la room 44918d67

socrative1

Quizz

quizz1

Quizz

quizz2

Quizz

quizz3

Quizz

quizz4

Quizz

quizz5

Quizz

quizz6

Quizz

quizz7

Quizz

quizz8

Quizz

quizz9

Quizz

quizz10

Quizz

quizz11

Quizz

quizz12

Quizz

quizz13